SNFFilter = { } -- public interface object

local SNFFilterdata = { }  -- private data object
local SNFFiltercache = { }  -- private data object

function SNFFilter:GetBaseListFromType(ftype)

--	SNFDEBUG(2, "GetBaseListFromType("..(ftype or "nil")..")")

	local list
	if ftype == "attend" or ftype == "loot" then
		list = { }
		for key, _ in pairs(SNFAttend:GetBaseAttendList()) do
			table.insert(list, key)
		end
		return list
	end

	return { }
end

function SNFFilter:FillFilterCache(filter, criteria, compareval)
	if not (criteria == "<" or criteria == ">" or criteria == "=" or criteria == "==") then
		SNFDEBUG(0, "Filter criteria, "..criteria.." not supported")
		return false
	end

	if not compareval then
		SNFDEBUG(0, "You must provide a comparison value")
		return false;
	end

	if not SNFFiltercache then SNFFiltercache = { } end

	-- start with a blank list
	SNFFiltercache[filter] = { }

	local source = SNFFilter:GetBaseListFromType(filter)

--	SNFDEBUG(2, "FillFilterCache("..(filter or "nil")..", "..(criteria or "nil")..", "..(compareval or "nil")..")")
	for _, key in pairs(source) do

--		SNFDEBUG(2, "Checking key: "..(key or "nil"))
		if (criteria == ">" and key > compareval) or
		   (criteria == "<" and key < compareval) or
		   (criteria == "=" and key == compareval) or
		   (criteria == "==" and key == compareval) then
--		   	SNFDEBUG(2, "Filter, insert to "..filter..", value "..key)
		   	table.insert(SNFFiltercache[filter], key)
		end
	end
end

function SNFFilter:ApplyFilters()
	if not SNFFilterdata then
		SNFDEBUG(0, "No filters to apply")
		return
	end

	for filter, data in ipairs(SNFFilterdata) do

		if filter == "attend" or filter == "loot" then
			SNFFilter:FillFilterCache(filter,
						  SNFFilterdata[filter]["criteria"],
						  SNFFilterdata[filter]["compareval"])
		end
	end
end

function SNFFilter:GetFilterSettings(filtertype)

	if filtertype ~= "attend" and filtertype ~= "loot" then
		SNFDEBUG(1, "Unknown filtertype passed to SNFFilter:GetFilterSettings")
		return nil, nil
	end
	if not SNFFilterdata[filtertype]  then
		SNFDEBUG(3, "Filter type "..(filtertype or "nil").." not set.")
		return nil, nil
	end
	return SNFFilterdata[filtertype]["criteria"], SNFFilterdata[filtertype]["compareval"]
end

function SNFFilter:SetFilter(ftype, criteria, compareval)

	if not (ftype == "attend" or ftype == "attend") then
		SNFDEBUG(0, "Filter type "..ftype.." is not supported.")
		return false
	end

	if not (criteria == "<" or criteria == ">" or criteria == "=" or criteria == "==") then
		SNFDEBUG(0, "Filter criteria, "..criteria.." not supported")
		return false
	end

	if not SNFFilterdata then SNFFilterdata = { } end
	if not SNFFilterdata[ftype] then SNFFilterdata[ftype] = { } end

	SNFFilterdata[ftype]["criteria"] = criteria
	SNFFilterdata[ftype]["compareval"] = compareval

	-- initial populate
	SNFFilter:FillFilterCache(ftype, criteria, compareval)
	SNFPlayer:ClearAllPlayerCounts()
	return true
end

function SNFFilter:RemoveFilter(ftype)

	if not (ftype == "attend" or ftype == "loot") then
		SNFDEBUG(0, "Filter type "..ftype.." is not supported.")
		return false
	end

	if not SNFFilterdata then return true end
	SNFFilterdata[ftype] = nil
	SNFFiltercache[ftype] = nil

	return true
end

function SNFFilter:GetFilteredList(ftype, sorted)

	if not (ftype == "attend" or ftype == "loot") then
		SNFDEBUG(0, "Filter type "..ftype.." is not supported.")
		return false
	end

	local list

	if SNFFiltercache and SNFFiltercache[ftype] then
		SNFDEBUG(2, "Using cached list: "..(ftype or "nil"))
		list = SNFFiltercache[ftype]
	else
		SNFDEBUG(2, "Using base list")
		list = SNFFilter:GetBaseListFromType(ftype)
	end

	if not list then
		local stext = "false"
		if sorted then stext = "true" end

		SNFDEBUG(1, "GetFilteredList("..(ftype or "nil")..","..stext..") found no list")
		return { }
	end

	if not sorted then return list end

	SNFDEBUG(3, "Returning sorted list");

	local srt

	local srt = { }
	for _, val in pairs(list) do
		table.insert(srt, val)
	end

	table.sort(srt)

	return srt
end